﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Zyg.Utility.Helper;

namespace Zyg.SSO.Core.Business
{
    public class AccountState
    {
        #region Properties

        private int id;
        /// <summary>
        /// Identifier of Account state
        /// </summary>
        public int ID
        {
            get { return id; }
        }

        private string name = String.Empty;
        /// <summary>
        /// Name of Account state
        /// </summary>
        public string Name
        {
            get { return name; }
        }

        #endregion

        #region Static elements

        public static readonly AccountState Register;

        public static readonly AccountState Active;

        public static readonly AccountState InActive;

        public static readonly AccountState All;

        #endregion

        #region Constructor

        static AccountState()
        {
            Register = new AccountState(1, "申请注册");
            Active = new AccountState(2, "注册成功");
            InActive = new AccountState(3, "注销");
            All = new AccountState(0, "全部状态");
        }

        protected AccountState()
        {
        }

        private AccountState(int id, string name)
        {
            this.id = id;
            this.name = name;
        }

        #endregion

        #region Converters

        /// <summary>
        /// Convert int to AccountState implicitly
        /// </summary>
        public static implicit operator AccountState(int id)
        {
            AccountState state;

            switch (id)
            {
                case 1:
                    state = AccountState.Register;
                    break;
                case 2:
                    state = AccountState.Active;
                    break;
                case 3:
                default:
                    state = AccountState.InActive;
                    break;
            }

            return state;
        }

        /// <summary>
        /// Convert AccountState to int explicitly
        /// </summary>
        public static explicit operator int(AccountState state)
        {
            if (state == null)
                throw new ArgumentNullException("state");

            int i;

            switch (state.ID)
            {
                case 2:
                    i = 2;
                    break;
                case 1:
                    i = 1;
                    break;
                case 3:
                default:
                    i = 3;
                    break;
            }

            return i;
        }

        #endregion

        #region Overloads

        public override string ToString()
        {
            return this.Name;
        }

        #endregion
    }

    public class Account : BusinessBase<Account, Guid>
    {
        public Account()
        {
            // apps = new AccountAppCollection(this, null, RelationType.ManyToMany);

            // apps.CollectionChanged += new EventHandler(delegate(object sender, EventArgs e) { this.MarkChanged("Apps"); });
            // base.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(OnPropertyChanged);
        }

        #region Fields and Properties

        private string name;
        /// <summary>
        /// Gets or sets the Name of the Account.
        /// </summary>
        public string Name
        {
            get { return name; }
            set
            {
                if (name != value)
                {
                    name = value;
                    MarkChanged("Name");
                }
            }
        }

        private Guid roleID = Guid.Empty;
        /// <summary>
        /// Gets or sets the RoleID of the Account.
        /// </summary>
        public Guid RoleID
        {
            get { return roleID; }
            set
            {
                if (roleID != value)
                {
                    roleID = value;
                    MarkChanged("RoleID");
                }
            }
        }

        private Role role;
        /// <summary>
        /// Get the role of account
        /// </summary>
        public Role Role
        {
            get
            {
                if (role == null || RoleID != role.Id)
                {
                    LoadRole();
                }

                return role;
            }
        }

        private string email = String.Empty;
        /// <summary>
        /// Gets or sets the Email of the Account.
        /// </summary>
        public string Email
        {
            get { return email; }
            set
            {
                if (email != value)
                {

                    email = value;
                    MarkChanged("Email");
                }
            }
        }

        private string password = String.Empty;
        /// <summary>
        /// Gets or sets the Password of the Account.
        /// </summary>
        public string Password
        {
            get { return password; }
            set
            {
                if (email != value)
                {
                    password = value;
                    MarkChanged("Password");
                }
            }
        }

        private AccountState state;
        /// <summary>
        /// Gets or sets the State of the Account.
        /// </summary>
        public AccountState State
        {
            get { return state; }
            set
            {
                if (state != value)
                {
                    state = value;
                    MarkChanged("State");
                }
            }
        }

        private bool isAdmin;
        /// <summary>
        /// Gets or sets wethere the Account is an admin.
        /// </summary>
        public bool IsAdmin
        {
            get { return isAdmin; }
            set
            {
                if (isAdmin != value)
                {
                    isAdmin = value;
                    MarkChanged("IsAdmin");
                }
            }
        }

        private string pictureAddress = String.Empty;
        /// <summary>
        /// Gets or sets the PictureAddress of the Account.
        /// </summary>
        public string PictureAddress
        {
            get { return pictureAddress; }
            set
            {
                if (pictureAddress != value)
                {
                    pictureAddress = value;
                    MarkChanged("PictureAddress");
                }
            }
        }

        private string telephone = String.Empty;
        /// <summary>
        /// Gets or sets the Telephone of the Account.
        /// </summary>
        public string Telephone
        {
            get { return telephone; }
            set
            {
                if (telephone != value)
                {
                    telephone = value;
                    MarkChanged("Telephone");
                }
            }
        }

        private string passQuestion = String.Empty;
        /// <summary>
        /// Gets or sets the PassQuestion of the Account.
        /// </summary>
        public string PassQuestion
        {
            get { return passQuestion; }
            set
            {
                if (passQuestion != value)
                {
                    passQuestion = value;
                    MarkChanged("PassQuestion");
                }
            }
        }

        private string passAnswer = String.Empty;
        /// <summary>
        /// Gets or sets the PassAnswer of the Account.
        /// </summary>
        public string PassAnswer
        {
            get { return passAnswer; }
            set
            {
                if (passAnswer != value)
                {
                    passAnswer = value;
                    MarkChanged("PassAnswer");
                }
            }
        }

        private string remark = String.Empty;
        /// <summary>
        /// Gets or sets the Remark of the Account.
        /// </summary>
        public string Remark
        {
            get { return remark; }
            set
            {
                if (remark != value)
                {
                    remark = value;
                    MarkChanged("Remark");
                }
            }
        }

        private AccountAppCollection apps = null;
        /// <summary>
        /// Get or set the applications that the account owns.
        /// </summary>
        public AccountAppCollection Apps
        {
            get
            {
                if (apps == null)
                    apps = new AccountAppCollection(this, null, RelationType.ManyToMany);
                return apps;
            }
            set
            {
                apps = value;
                MarkChanged("Apps");
            }
        }

        #endregion

        #region Base overrides

        protected override void ValidationRules()
        {
            AddRule("NameLengthBound", "账户名称长度必须在1与100个字符之间", !Name.IsInLengthBound(1, 100));
            AddRule("Email", "账户邮箱格式不正确", !Email.IsEmail());
            AddRule("PictureAddress", "图片格式不正确,必须为jp(e)g,gif,bmp或者png格式!", !(PictureAddress.IsNullOrEmpty() || PictureAddress.IsImage()));
        }

        protected override Account DataSelect(Guid id)
        {
            return Services.DALService.SelectAccount(id);
        }

        protected override void DataUpdate()
        {
            Services.DALService.UpdateAccount(this);
        }

        protected override void DataInsert()
        {
            Services.DALService.InsertAccount(this);
        }

        protected override void DataDelete()
        {
            Services.DALService.DeleteAccount(this);
        }

        public override SaveAction Save()
        {
            if (this.IsDeleted && !this.IsNew)
            {
                this.Apps.ClearOnSave();
                this.Apps.Save();
            }

            SaveAction action = base.Save();

            if (apps != null)
                Apps.Save();

            return action;
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 获取当前用户是否是某项权限
        /// </summary>
        public bool HavePermission(Permission permission)
        {
            foreach (Permission per in Role.Permissions)
            {
                if (per.ID == permission.ID)
                    return true;
            }

            return false;
        }

        #endregion

        #region Static Methods

        public static Account Load(string email)
        {
            return Services.DALService.SelectAccount(email);
        }

        public static bool Exist(string email)
        {
            return Services.DALService.ExistsAccount(email);
        }

        public static IList<Account> GetAccountsByEmail(string email)
        {
            return Services.DALService.FillAccounts(
                email,
                String.Empty,
                AccountState.All,
                new Nullable<Boolean>(),
                new Nullable<Guid>(),
                new Nullable<DateTime>(),
                new Nullable<DateTime>(),
                new Nullable<Int32>(),
                new Nullable<Int32>()
            );
        }

        public static IList<Account> GetAccountsByAdminType(bool isAdmin)
        {
            return Services.DALService.FillAccounts(
                String.Empty,
                String.Empty,
                AccountState.All,
                isAdmin,
                new Nullable<Guid>(),
                new Nullable<DateTime>(),
                new Nullable<DateTime>(),
                new Nullable<Int32>(),
                new Nullable<Int32>()
            );
        }

        public static IList<Account> GetAccountsByName(string name)
        {
            return Services.DALService.FillAccounts(
                String.Empty,
                name,
                AccountState.All,
                new Nullable<Boolean>(),
                new Nullable<Guid>(),
                new Nullable<DateTime>(),
                new Nullable<DateTime>(),
                new Nullable<Int32>(),
                new Nullable<Int32>()
            );
        }

        public static IList<Account> GetAccountsByState(AccountState state)
        {
            return Services.DALService.FillAccounts(
                String.Empty,
                String.Empty,
                state,
                new Nullable<Boolean>(),
                new Nullable<Guid>(),
                new Nullable<DateTime>(),
                new Nullable<DateTime>(),
                new Nullable<Int32>(),
                new Nullable<Int32>()
            );
        }

        public static IList<Account> GetAccounts(bool isAdmin, AccountState state)
        {
            return Services.DALService.FillAccounts(
                String.Empty,
                String.Empty,
                state,
                isAdmin,
                new Nullable<Guid>(),
                new Nullable<DateTime>(),
                new Nullable<DateTime>(),
                new Nullable<Int32>(),
                new Nullable<Int32>()
            );
        }

        public static IList<Business.Account> GetAccounts(string email, string name, Business.AccountState state, bool? isAdmin, Guid? roleId, DateTime? startTime, DateTime? endTime, int? startIndex, int? endIndex)
        {
            return Services.DALService.FillAccounts(email, name, state, isAdmin, roleId, startTime, endTime, startIndex, endIndex);
        }


        public static System.Data.DataTable ToDataTable(IList<Business.Account> accounts)
        {
            System.Data.DataTable dt = new System.Data.DataTable();

            dt.Columns.Add("Id");
            dt.Columns.Add("Email");
            dt.Columns.Add("Name");
            dt.Columns.Add("State");
            dt.Columns.Add("DateCreated", typeof(System.DateTime));
            dt.Columns.Add("Remark");

            foreach (Account account in accounts)
            {
                dt.Rows.Add(account.Id,
                    account.Email,
                    account.Name,
                    account.State,
                    account.DateCreated,
                    account.Remark
                    );
            }

            return dt;
        }


        #endregion

        #region Private Methods

        private void LoadRole()
        {
            role = Role.Load(this.RoleID);
        }

        #endregion

        #region Events

        protected void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Name")
            {
                System.Diagnostics.Debug.Write("Name Changed");
            }
        }

        #endregion

    }
}
